﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace Centny
{
    public partial class ExtScrollViewer : ExtBaseGrid
    {
        //public enum ExtScrollMode
        //{
        //    Normal = 1, Page
        //}
        public ScrollViewer SViewer { get; set; }
        //public ExtScrollMode SMode { get; set; }
        public ExtScrollViewer()
        {
            //this.SMode = ExtScrollMode.Page;
            //this.Loaded += OnLoaded;
        }
        protected override void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (this.Children.Count < 1)
            {
                return;
            }
            this.SViewer = this.Children[0] as ScrollViewer;
            if (this.SViewer == null)
            {
                throw new InvalidCastException("the ExtScrollViewer content is not a ScrollViewer");
            }
            //this.SViewer.ViewChanged += OnViewChanged;
            //this.OnLoadeCompleted();
        }
        //protected virtual void OnLoadeCompleted()
        //{
        //}
        //private Double CurrentHorOffset = 0;
        //private Double CurrentVerOffset = 0;
        //private Double StartHorOffset = -1;
        //private Double StartVerOffset = -1;
        //private bool Executing = false;
        //private void OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
        //{
        //    if (this.SMode == ExtScrollMode.Normal || this.Executing)
        //    {
        //        return;
        //    }      
        //    if (this.StartHorOffset < 0)
        //    {
        //        this.StartHorOffset = this.SViewer.HorizontalOffset;
        //    }
        //    if (this.StartVerOffset < 0)
        //    {
        //        this.StartVerOffset = this.SViewer.VerticalOffset;
        //    }
        //    Double HOffset = this.SViewer.HorizontalOffset - this.StartHorOffset;
        //    Double VOffset = this.SViewer.VerticalOffset - this.StartVerOffset;
        //    if (Math.Abs(HOffset) < 100 && Math.Abs(VOffset) < 100)
        //    {
        //        if (!e.IsIntermediate)
        //        {
        //            this.SViewer.ScrollToHorizontalOffset(this.CurrentHorOffset);
        //            this.SViewer.ScrollToVerticalOffset(this.CurrentVerOffset);
        //        }
        //        return;
        //    }
        //    if (this.CurrentHorOffset < 1 && HOffset < 0)
        //    {
        //        return;
        //    }
        //    if (this.CurrentVerOffset < 1 && VOffset < 0)
        //    {
        //        return;
        //    }
        //    if (this.SViewer.ExtentWidth - this.SViewer.ActualWidth < this.CurrentHorOffset && HOffset > 0)
        //    {
        //        return;
        //    }
        //    if (this.SViewer.ExtentHeight - this.SViewer.ActualHeight < this.CurrentVerOffset && VOffset > 0)
        //    {
        //        return;
        //    }
        //    Double NOffset;
        //    if (Math.Abs(HOffset) > Math.Abs(VOffset))
        //    {
        //        this.Executing = true;
        //        if (HOffset > 0)
        //        {
        //            NOffset = this.CurrentHorOffset + this.SViewer.ActualWidth;
        //        }
        //        else
        //        {
        //            NOffset = this.CurrentHorOffset - this.SViewer.ActualWidth;
        //        }
        //        if (NOffset < 0)
        //        {
        //            NOffset = 0;
        //        }
        //        else if (NOffset > this.SViewer.ExtentWidth - this.SViewer.ActualWidth)
        //        {
        //            NOffset = this.SViewer.ExtentWidth - this.SViewer.ActualWidth;
        //        }
        //        this.ScrollAnimationHorOffset(NOffset);
        //        this.CurrentHorOffset = NOffset;
        //    }
        //    else
        //    {
        //        this.Executing = true;
        //        if (VOffset > 0)
        //        {
        //            NOffset = this.CurrentVerOffset + this.SViewer.ActualHeight;
        //        }
        //        else
        //        {
        //            NOffset = this.CurrentVerOffset - this.SViewer.ActualHeight;
        //        }
        //        if (NOffset < 0)
        //        {
        //            NOffset = 0;
        //        }
        //        else if (NOffset > this.SViewer.Height - this.SViewer.ActualHeight)
        //        {
        //            NOffset = this.SViewer.Height - this.SViewer.ActualHeight;
        //        }
        //        this.ScrollAnimationVerOffset(NOffset);
        //        this.CurrentVerOffset = NOffset;
        //    }
        //}
        private List<EventHandler<object>> _AnimationCompleted = new List<EventHandler<object>>();
        public event EventHandler<object> AnimationCompleted
        {
            add
            {
                this._AnimationCompleted.Add(value);
            }
            remove
            {
                this._AnimationCompleted.Remove(value);
            }
        }
        public void ScrollAnimationHorOffset(double offset)
        {
            DoubleAnimation an = new DoubleAnimation();
            an.Duration = new Duration(TimeSpan.FromMilliseconds(500));
            an.EnableDependentAnimation = true;
            an.From = this.SViewer.HorizontalOffset;
            an.To = offset;
            Storyboard.SetTarget(an, this);
            Storyboard.SetTargetProperty(an, "HorOffset");
            Storyboard storyboard = new Storyboard();
            foreach (EventHandler<object> eh in this._AnimationCompleted)
            {
                storyboard.Completed += eh;
            }
            storyboard.Children.Add(an);
            storyboard.Begin();
        }
        public void ScrollAnimationVerOffset(double offset)
        {
            DoubleAnimation an = new DoubleAnimation();
            an.Duration = new Duration(TimeSpan.FromMilliseconds(500));
            an.EnableDependentAnimation = true;
            an.From = this.SViewer.VerticalOffset;
            an.To = offset;
            Storyboard.SetTarget(an, this);
            Storyboard.SetTargetProperty(an, "VerOffset");
            Storyboard storyboard = new Storyboard();
            foreach (EventHandler<object> eh in this._AnimationCompleted)
            {
                storyboard.Completed += eh;
            }
            storyboard.Children.Add(an);
            storyboard.Begin();
        }
        #region Property.
        private static void OnHorOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ExtScrollViewer esv = d as ExtScrollViewer;
            if (esv == null || esv.SViewer == null)
            {
                return;
            }
            Double val = (Double)e.NewValue;
            esv.SViewer.ScrollToHorizontalOffset(val);
        }
        public static readonly DependencyProperty HorOffsetProperty = DependencyProperty.Register("HorOffset", typeof(Double), typeof(ExtScrollViewer), new PropertyMetadata(0, OnHorOffsetChanged));
        public Double HorOffset
        {
            get
            {
                return (Double)this.GetValue(HorOffsetProperty);
            }
            set
            {
                this.SetValue(HorOffsetProperty, value);
            }
        }
        private static void OnVerOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ExtScrollViewer esv = d as ExtScrollViewer;
            if (esv == null || esv.SViewer == null)
            {
                return;
            }
            Double val = (Double)e.NewValue;
            esv.SViewer.ScrollToVerticalOffset(val);
        }
        public static readonly DependencyProperty VerOffsetProperty = DependencyProperty.Register("VerOffset", typeof(Double), typeof(ExtScrollViewer), new PropertyMetadata(0, OnVerOffsetChanged));
        public Double VerOffset
        {
            get
            {
                return (Double)this.GetValue(VerOffsetProperty);
            }
            set
            {
                this.SetValue(VerOffsetProperty, value);
            }
        }
        #endregion
    }
}
